package com.cskaoyan.javase.object._2tostring;

/**
 * toString方法
 * 1.方法的声明：public String toString()
 *      没有什么注意的，该方法是无参的，返回值是一个字符串
 *
 * 2.方法的作用：
 *      关于toString方法的作用，在JDK文档中，有详细的说明，主要说以下四点：
 *          1.返回该对象（调用toString方法的对象）的字符串表示。
 *          2.通常，toString方法会返回一个"以文本方式表示"此对象的字符串。
 *          3.结果应是一个简明但易于读懂的信息表达式。
 *  *          4.建议所有子类都重写此方法。
 *
 * 3.Object类当中toString方法的默认实现：
 *       return getClass().getName() + "@" + Integer.toHexString(hashCode());
 *       解释：
 *       getClass().getName()是获取该类的全限定类名
 *
 *       Integer.toHexString() 该方法是将一个十进制的int整数转换成它对应的十六进制字符串
 *       hashCode()是Object类当中的方法，默认情况下，不重写它的情况下，它是通过计算对象的内存地址得到一个十进制的整数
 *          可以认为这个十进制的整数就是对象的地址值
 *       所以Integer.toHexString(hashCode())整体就表示该对象的十六进制地址值字符串
 *
 *       所以默认实现就是打印： 全限定类名 + @ + 十六进制地址值
 *       显然直接打印引用得到的就是以上字符串。
 *
 * 4.toString方法的调用场景
 *      在Java中如果直接输出一个引用或者使用引用参与字符串拼接操作，那么就隐式调用toString方法
 *      是toString方法的返回值在参与运算。
 *
 *
 * 5.toString方法的重写
 *      在绝大多数情况下，toString方法的默认实现意义不大，地址值之类的东西我们不想看见
 *      所以就需要在子类中重写它的实现
 *      toString方法的重写最常见的就是打印属性的取值。
 *
 *  注意事项
 *      1.toString绝大情况下就是为了打印对象属性取值的,格式十分固定,所以不要手写
 *          而是使用快捷键 alt + insert 自动生成
 *      2.toString方法就仅做打印属性的操作,不要在里面乱写代码,尤其是赋值等业务语句,不要写进去
 *          最合理的情况下,就是自动生成它,不要手写它.
 *          尤其是debug模式下,当debug走过创建对象以及使用引用的语句时,会自动调用toString方法
 *          来打印对象的信息
 *          这时如果toString方法乱写就会导致问题.
 *
 *      3.如果类中有引用数据类型成员变量
 *          写toString方法时
 *          往往需要重写该引用数据类型成员变量所在类的toString方法
 *
 *      4.在引用参与字符串拼接运算时,不要画蛇添足写出toString方法调用.(因为有可能产生空指针异常)
 *
 *
 * @since 10:38
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
       /* Student s = new Student(18, "张三");
        // System.out.println(s);
        // System.out.println(s + "123");
        System.out.println(s.age);*/

        Student s = new Student(18, "李四", new A(666));
        System.out.println(s);

        Student s2 = new Student(28, "小红", null);
        System.out.println(s2);
    }
}

class Student {
    int age;
    String name;
    A a;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Student(int age, String name, A a) {
        this.age = age;
        this.name = name;
        this.a = a;
    }
    /*@Override
    public String toString() {
        return "Student:{ age = " + age + ",name = " + name +
                "}";
    }*/

    /*@Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", a=" + a +
                '}';
    }
}

class A {
    int num = 10;

    public A(int num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "A{" +
                "num=" + num +
                '}';
    }

}